/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.rbac.service.grant.impl;

import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.je.common.base.DynaBean;
import com.je.common.base.context.GlobalExtendedContext;
import com.je.common.base.service.MetaService;
import com.je.common.base.service.rpc.BeanService;
import com.je.common.base.util.StringUtil;
import com.je.common.base.util.TreeUtil;
import com.je.core.entity.extjs.JSONTreeNode;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.meta.rpc.func.MetaFuncRpcService;
import com.je.rbac.service.grant.RbacGrantTreeService;
import com.je.rbac.service.grant.department.RbacGrantDepartmentTreeService;
import com.je.rbac.service.grant.develop.RbacGrantDevelopTreeService;
import com.je.rbac.service.grant.org.RbacGrantOrgTreeService;
import com.je.rbac.service.grant.permgroup.RbacGrantPermGroupTreeService;
import com.je.rbac.service.grant.role.RbacGrantRoleTreeService;
import com.je.rbac.service.permission.GrantTypeEnum;
import com.je.rbac.service.permission.template.PcSubFuncRelationService;
import com.je.rbac.service.permission.template.PcFuncBaseService;
import com.je.rbac.service.permission.template.PcFuncButtonService;
import com.je.rbac.service.permission.template.PcMenuDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class RbacGrantTreeServiceImpl implements RbacGrantTreeService {

    @Autowired
    private MetaService metaService;
    @Autowired
    private MetaFuncRpcService metaFuncRpcService;
    @Autowired
    private BeanService beanService;
    @Autowired
    private PcFuncBaseService pcFuncBaseService;
    @Autowired
    private PcSubFuncRelationService pcSubFuncRelationService;
    @Autowired
    private PcFuncButtonService pcFuncButtonService;
    @Autowired
    private PcMenuDataService pcMenuDataService;
    @Autowired
    private RbacGrantRoleTreeService rbacGrantRoleTreeService;
    @Autowired
    private RbacGrantDepartmentTreeService rbacGrantDepartmentTreeService;
    @Autowired
    private RbacGrantOrgTreeService rbacGrantOrgTreeService;
    @Autowired
    private RbacGrantPermGroupTreeService rbacGrantPermGroupTreeService;
    @Autowired
    private RbacGrantDevelopTreeService rbacGrantDevelopTreeService;

    @Override
    public JSONTreeNode loadAccountMenuPermissions(String accountId) {
        JSONTreeNode rootNode = TreeUtil.buildRootNode();
        DynaBean table = beanService.getResourceTable("JE_CORE_MENU");
        List<DynaBean> columns = (List<DynaBean>) table.get(BeanService.KEY_TABLE_COLUMNS);
        JSONTreeNode template = beanService.buildJSONTreeNodeTemplate(columns);

        DynaBean accountBean = metaService.selectOne("JE_RBAC_ACCOUNT", ConditionsWrapper.builder().eq("JE_RBAC_ACCOUNT_ID", accountId));
        if (accountBean == null) {
            return rootNode;
        }

        List<DynaBean> menuBeanList = metaService.select("JE_CORE_MENU", ConditionsWrapper.builder().ne("SY_NODETYPE", "ROOT").orderByAsc("SY_TREEORDERINDEX"));
        List<String> funcCodeList = new ArrayList<>();
        for (DynaBean eachBean : menuBeanList) {
            if ("MT".equals(eachBean.getStr("MENU_NODEINFOTYPE"))) {
                funcCodeList.add(eachBean.getStr("MENU_NODEINFO"));
                eachBean.set("MENU_MENUNAME", eachBean.getStr("MENU_MENUNAME") + "->功能");
            } else if ("MENU".equals(eachBean.getStr("MENU_NODEINFOTYPE"))) {
                eachBean.set("MENU_MENUNAME", eachBean.getStr("MENU_MENUNAME") + "->菜单");
            } else if ("IFRAME".equals(eachBean.getStr("MENU_NODEINFOTYPE"))) {
                eachBean.set("MENU_MENUNAME", eachBean.getStr("MENU_MENUNAME") + "->IFRAME");
            } else if ("IDDT".equals(eachBean.getStr("MENU_NODEINFOTYPE"))) {
                eachBean.set("MENU_MENUNAME", eachBean.getStr("MENU_MENUNAME") + "->自定义");
            } else if ("PORTAL".equals(eachBean.getStr("MENU_NODEINFOTYPE"))) {
                eachBean.set("MENU_MENUNAME", eachBean.getStr("MENU_MENUNAME") + "->门户");
            } else if ("REPORT".equals(eachBean.getStr("MENU_NODEINFOTYPE"))) {
                eachBean.set("MENU_MENUNAME", eachBean.getStr("MENU_MENUNAME") + "->报表");
            } else if ("URL".equals(eachBean.getStr("MENU_NODEINFOTYPE"))) {
                eachBean.set("MENU_MENUNAME", eachBean.getStr("MENU_MENUNAME") + "->超链接");
            } else if ("CHART".equals(eachBean.getStr("MENU_NODEINFOTYPE"))) {
                eachBean.set("MENU_MENUNAME", eachBean.getStr("MENU_MENUNAME") + "->图表");
            } else if ("DIC".equals(eachBean.getStr("MENU_NODEINFOTYPE"))) {
                eachBean.set("MENU_MENUNAME", eachBean.getStr("MENU_MENUNAME") + "->字典功能");
            }
        }

        JSONTreeNode node;
        for (DynaBean eachMenuBean : menuBeanList) {
            if ("ROOT".equals(eachMenuBean.getStr("SY_PARENT"))) {
                node = buildTreeNode(template, "ROOT", eachMenuBean);
                rootNode.getChildren().add(node);
            }
        }

        //递归形成树形结构
        for (JSONTreeNode eachNode : rootNode.getChildren()) {
            recursiveJsonTreeNode(template, eachNode, menuBeanList);
        }
        Map<String, List<DynaBean>> funcResult = metaFuncRpcService.findPermedFuncsAndChildFuncsWithButtonsByFuncCodes(funcCodeList);
        //功能
        List<DynaBean> mainFuncList = funcResult.get("main");
        //子功能
        List<DynaBean> childFuncRelationList = funcResult.get("child");
        //按钮
        List<DynaBean> funcButtonList = funcResult.get("button") == null ? new ArrayList<>() : funcResult.get("button");
        //子功能所属功能
        List<String> subFuncRelationIdList = new ArrayList<>();
        if (childFuncRelationList != null && !childFuncRelationList.isEmpty()) {
            childFuncRelationList.forEach(each -> {
                subFuncRelationIdList.add(each.getStr("JE_CORE_FUNCRELATION_ID"));
            });
        }
        Map<String, DynaBean> funcIdCodeMap = metaFuncRpcService.findSubFuncParentFuncInfos(subFuncRelationIdList);

        //主功能
        for (DynaBean eachFuncBean : mainFuncList) {
            //此处设置功能展示权限，用于check校验
            eachFuncBean.set("PERM_SHOW", pcFuncBaseService.formatPcFuncShowTemplate(eachFuncBean.getStr("FUNCINFO_FUNCCODE")));
            //设置功能按钮的功能属性，用于构建树形
            for (DynaBean eachButtonBean : funcButtonList) {
                if (eachFuncBean.getStr("JE_CORE_FUNCINFO_ID").equals(eachButtonBean.getStr("RESOURCEBUTTON_FUNCINFO_ID"))) {
                    eachButtonBean.set("FUNCINFO_FUNCCODE", eachFuncBean.getStr("FUNCINFO_FUNCCODE"));
                    //此处生成展示权限编码，用于check校验
                    eachButtonBean.set("PERM_SHOW", pcFuncButtonService.formatPcFuncButtonShowTemplate(eachFuncBean.getStr("FUNCINFO_FUNCCODE"),
                            eachButtonBean.getStr("RESOURCEBUTTON_CODE")));
                }
            }
        }

        //子功能
        for (int i = 0; childFuncRelationList != null && !childFuncRelationList.isEmpty() && i < childFuncRelationList.size(); i++) {
            //此处设置子功能展示权限，用于check校验
            if ("func".equals(childFuncRelationList.get(i).getStr("FUNCRELATION_RELYONTYPE"))) {
                childFuncRelationList.get(i).set("PERM_SHOW", pcSubFuncRelationService.formatPcSubFuncRelationShowTemplate(getFuncCode(funcIdCodeMap.get(childFuncRelationList.get(i).getStr("JE_CORE_FUNCRELATION_ID"))), childFuncRelationList.get(i).getStr("FUNCRELATION_CODE")));
                //设置功能按钮的功能属性，用于构建树形
                for (DynaBean eachButtonBean : funcButtonList) {
                    if (childFuncRelationList.get(i).getStr("FUNCRELATION_FUNCID").equals(eachButtonBean.getStr("RESOURCEBUTTON_FUNCINFO_ID"))) {
                        eachButtonBean.set("FUNCINFO_FUNCCODE", childFuncRelationList.get(i).getStr("FUNCRELATION_CODE"));
                        //此处生成展示权限编码，用于check校验
                        eachButtonBean.set("PERM_SHOW", pcFuncButtonService.formatPcFuncButtonShowTemplate(childFuncRelationList.get(i).getStr("FUNCRELATION_CODE"),
                                eachButtonBean.getStr("RESOURCEBUTTON_CODE")));
                    }
                }
            } else {
                childFuncRelationList.get(i).set("PERM_SHOW", pcSubFuncRelationService.formatPcSubFuncRelationShowTemplate(getFuncCode(funcIdCodeMap.get(childFuncRelationList.get(i).getStr("JE_CORE_FUNCRELATION_ID"))), childFuncRelationList.get(i).getStr("FUNCRELATION_CODE")));
            }
        }

        //递归设置功能按钮和子功能
        recursiveSetMenuFuncInfo(rootNode, mainFuncList, childFuncRelationList, funcButtonList);

        List<DynaBean> accountRoleBeanList = metaService.select("JE_RBAC_ACCOUNTROLE", ConditionsWrapper.builder().eq("ACCOUNTROLE_ACCOUNT_ID", accountId));
        List<String> roleIdList = new ArrayList<>();
        List<String> departmentIdList = new ArrayList<>();
        for (DynaBean eachAccountRoleBean : accountRoleBeanList) {
            roleIdList.add(eachAccountRoleBean.getStr("ACCOUNTROLE_ROLE_ID"));
            departmentIdList.add(eachAccountRoleBean.getStr("ACCOUNTROLE_DEPT_ID"));
        }
        //权限校验check
        rbacGrantRoleTreeService.checkWithRole(GrantTypeEnum.MENU, Joiner.on(",").join(roleIdList), rootNode);
        rbacGrantDepartmentTreeService.checkWithDepartment(GrantTypeEnum.MENU, Joiner.on(",").join(departmentIdList), rootNode);
        rbacGrantOrgTreeService.checkWithOrg(GrantTypeEnum.MENU, accountBean.getStr("SY_ORG_ID"), rootNode);
        JSONTreeNode filteredRootNode = TreeUtil.buildRootNode();
        JSONTreeNode eachFilteredNode;
        for (JSONTreeNode eachNode : rootNode.getChildren()) {
            eachFilteredNode = recursiveFilterUnCheckedNodes(eachNode);
            if (eachFilteredNode != null) {
                filteredRootNode.getChildren().add(eachFilteredNode);
            }
        }
        return filteredRootNode;
    }

    private JSONTreeNode recursiveFilterUnCheckedNodes(JSONTreeNode node) {
        if (!node.getChecked()) {
            return null;
        }
        JSONTreeNode filterNode = new JSONTreeNode();
        filterNode.setId(node.getId());
        filterNode.setCode(node.getCode());
        filterNode.setText(node.getText());
        filterNode.setChecked(node.getChecked());
        filterNode.setNodeInfo(node.getNodeInfo());
        filterNode.setBean(node.getBean());
        filterNode.setNodeType(node.getNodeType());
        filterNode.setNodeInfoType(node.getNodeInfoType());
        filterNode.setExpanded(node.getExpanded());
        filterNode.setParent(node.getParent());
        filterNode.setLayer(node.getLayer());
        filterNode.setLeaf(node.isLeaf());
        filterNode.setIcon(node.getIcon());
        filterNode.setIconColor(node.getIconColor());
        filterNode.setDisabled(node.getDisabled());
        filterNode.setTreeOrderIndex(node.getTreeOrderIndex());
        filterNode.setAsync(node.isAsync());
        filterNode.setNodePath(node.getNodePath());
        filterNode.setDescription(node.getDescription());
        filterNode.setOrderIndex(node.getOrderIndex());
        filterNode.setExpandable(node.isExpandable());
        JSONTreeNode eachFilterNode;
        for (JSONTreeNode eachNode : node.getChildren()) {
            eachFilterNode = recursiveFilterUnCheckedNodes(eachNode);
            if (eachFilterNode != null) {
                filterNode.getChildren().add(eachFilterNode);
            }
        }
        return filterNode;
    }

    private String getFuncCode(DynaBean funcBean) {
        if (funcBean == null) {
            return null;
        }
        return funcBean.getStr("FUNCINFO_FUNCCODE");
    }

    private void wrapperThreeMemberMenus(ConditionsWrapper wrapper) {
        List<String> menuIdList = new ArrayList<>();
        List<DynaBean> beanList = metaService.select("JE_RBAC_RESOURCESCOPE", ConditionsWrapper.builder().orderByDesc("SY_CREATETIME"));
        if (beanList != null && !beanList.isEmpty()) {
            for (int i = 0; i < beanList.size(); i++) {
                if (!Strings.isNullOrEmpty(beanList.get(i).getStr("RESOURCESCOPE_MENU_ID"))) {
                    menuIdList.addAll(Splitter.on(",").splitToList(beanList.get(i).getStr("RESOURCESCOPE_MENU_ID")));
                }
            }
            wrapper.notIn("JE_CORE_MENU_ID", menuIdList);
        }
    }

    @Override
    public JSONTreeNode loadMenuPermissions(String type, String ids, String topMenuId) {
        ConditionsWrapper menuWrapper = ConditionsWrapper.builder().like("SY_PATH", topMenuId);
        if (!"develop".equals(type) && "1".equals(GlobalExtendedContext.getContextKey("switch"))) {
            wrapperThreeMemberMenus(menuWrapper);
        }
        menuWrapper.orderByAsc("SY_TREEORDERINDEX");
        List<DynaBean> menuBeanList = metaService.select("JE_CORE_MENU", menuWrapper);
        List<String> funcCodeList = new ArrayList<>();
        for (DynaBean eachBean : menuBeanList) {
            if ("MT".equals(eachBean.getStr("MENU_NODEINFOTYPE"))) {
                funcCodeList.add(eachBean.getStr("MENU_NODEINFO"));
                eachBean.set("MENU_MENUNAME", eachBean.getStr("MENU_MENUNAME") + "->功能");
            } else if ("MENU".equals(eachBean.getStr("MENU_NODEINFOTYPE"))) {
                eachBean.set("MENU_MENUNAME", eachBean.getStr("MENU_MENUNAME") + "->菜单");
            } else if ("IFRAME".equals(eachBean.getStr("MENU_NODEINFOTYPE"))) {
                eachBean.set("MENU_MENUNAME", eachBean.getStr("MENU_MENUNAME") + "->IFRAME");
            } else if ("IDDT".equals(eachBean.getStr("MENU_NODEINFOTYPE"))) {
                eachBean.set("MENU_MENUNAME", eachBean.getStr("MENU_MENUNAME") + "->自定义");
            } else if ("PORTAL".equals(eachBean.getStr("MENU_NODEINFOTYPE"))) {
                eachBean.set("MENU_MENUNAME", eachBean.getStr("MENU_MENUNAME") + "->门户");
            } else if ("REPORT".equals(eachBean.getStr("MENU_NODEINFOTYPE"))) {
                eachBean.set("MENU_MENUNAME", eachBean.getStr("MENU_MENUNAME") + "->报表");
            } else if ("URL".equals(eachBean.getStr("MENU_NODEINFOTYPE"))) {
                eachBean.set("MENU_MENUNAME", eachBean.getStr("MENU_MENUNAME") + "->超链接");
            } else if ("CHART".equals(eachBean.getStr("MENU_NODEINFOTYPE"))) {
                eachBean.set("MENU_MENUNAME", eachBean.getStr("MENU_MENUNAME") + "->图表");
            } else if ("DIC".equals(eachBean.getStr("MENU_NODEINFOTYPE"))) {
                eachBean.set("MENU_MENUNAME", eachBean.getStr("MENU_MENUNAME") + "->字典功能");
            }
        }

        Map<String, List<DynaBean>> funcResult = metaFuncRpcService.findPermedFuncsAndChildFuncsWithButtonsByFuncCodes(funcCodeList);
        JSONTreeNode rootNode = TreeUtil.buildRootNode();
        DynaBean table = beanService.getResourceTable("JE_CORE_MENU");
        List<DynaBean> columns = (List<DynaBean>) table.get(BeanService.KEY_TABLE_COLUMNS);
        JSONTreeNode template = beanService.buildJSONTreeNodeTemplate(columns);
        JSONTreeNode node;
        for (DynaBean eachMenuBean : menuBeanList) {
            if (topMenuId.equals(eachMenuBean.getStr("JE_CORE_MENU_ID"))) {
                node = buildTreeNode(template, "ROOT", eachMenuBean);
                if ("MT".equals(node.getNodeInfoType())) {
                    node.setIcon("jeicon jeicon-function");
                }
                node.setNodeInfo(topMenuId);
                rootNode.getChildren().add(node);
            }
        }

        //递归形成树形结构
        for (JSONTreeNode eachNode : rootNode.getChildren()) {
            recursiveJsonTreeNode(template, eachNode, menuBeanList);
        }

        //功能
        List<DynaBean> mainFuncList = funcResult.get("main");
        //子功能
        List<DynaBean> childFuncRelationList = funcResult.get("child");
        //按钮
        List<DynaBean> funcButtonList = funcResult.get("button") == null ? new ArrayList<>() : funcResult.get("button");
        //子功能所属功能
        List<String> subFuncRelationIdList = new ArrayList<>();
        if (childFuncRelationList != null && !childFuncRelationList.isEmpty()) {
            childFuncRelationList.forEach(each -> {
                subFuncRelationIdList.add(each.getStr("JE_CORE_FUNCRELATION_ID"));
            });
        }
        Map<String, DynaBean> funcIdCodeMap = metaFuncRpcService.findSubFuncParentFuncInfos(subFuncRelationIdList);

        //主功能
        for (DynaBean eachFuncBean : mainFuncList) {
            //此处设置功能展示权限，用于check校验
            eachFuncBean.set("PERM_SHOW", pcFuncBaseService.formatPcFuncShowTemplate(eachFuncBean.getStr("FUNCINFO_FUNCCODE")));
            //设置功能按钮的功能属性，用于构建树形
            for (DynaBean eachButtonBean : funcButtonList) {
                if (eachFuncBean.getStr("JE_CORE_FUNCINFO_ID").equals(eachButtonBean.getStr("RESOURCEBUTTON_FUNCINFO_ID"))) {
                    eachButtonBean.set("FUNCINFO_FUNCCODE", eachFuncBean.getStr("FUNCINFO_FUNCCODE"));
                    //此处生成展示权限编码，用于check校验
                    eachButtonBean.set("PERM_SHOW", pcFuncButtonService.formatPcFuncButtonShowTemplate(eachFuncBean.getStr("FUNCINFO_FUNCCODE"),
                            eachButtonBean.getStr("RESOURCEBUTTON_CODE")));
                }
            }
        }

        //子功能
        for (int i = 0; childFuncRelationList != null && !childFuncRelationList.isEmpty() && i < childFuncRelationList.size(); i++) {
            //此处设置子功能展示权限，用于check校验
            if ("func".equals(childFuncRelationList.get(i).getStr("FUNCRELATION_RELYONTYPE"))) {
                childFuncRelationList.get(i).set("PERM_SHOW", pcSubFuncRelationService.formatPcSubFuncRelationShowTemplate(getFuncCode(funcIdCodeMap.get(childFuncRelationList.get(i).getStr("JE_CORE_FUNCRELATION_ID"))), childFuncRelationList.get(i).getStr("FUNCRELATION_CODE")));
                //设置功能按钮的功能属性，用于构建树形
                for (DynaBean eachButtonBean : funcButtonList) {
                    if (childFuncRelationList.get(i).getStr("FUNCRELATION_FUNCID").equals(eachButtonBean.getStr("RESOURCEBUTTON_FUNCINFO_ID"))) {
                        eachButtonBean.set("FUNCINFO_FUNCCODE", childFuncRelationList.get(i).getStr("FUNCRELATION_CODE"));
                        //此处生成展示权限编码，用于check校验
                        eachButtonBean.set("PERM_SHOW", pcFuncButtonService.formatPcFuncButtonShowTemplate(childFuncRelationList.get(i).getStr("FUNCRELATION_CODE"),
                                eachButtonBean.getStr("RESOURCEBUTTON_CODE")));
                    }
                }
            } else {
                childFuncRelationList.get(i).set("PERM_SHOW", pcSubFuncRelationService.formatPcSubFuncRelationShowTemplate(getFuncCode(funcIdCodeMap.get(childFuncRelationList.get(i).getStr("JE_CORE_FUNCRELATION_ID"))), childFuncRelationList.get(i).getStr("FUNCRELATION_CODE")));
            }
        }

        //递归设置功能按钮和子功能
        recursiveSetMenuFuncInfo(rootNode, mainFuncList, childFuncRelationList, funcButtonList);

        //权限校验check
        if ("role".equals(type)) {
            rbacGrantRoleTreeService.checkWithRole(GrantTypeEnum.MENU, ids, rootNode);
        } else if ("department".equals(type)) {
            rbacGrantDepartmentTreeService.checkWithDepartment(GrantTypeEnum.MENU, ids, rootNode);
        } else if ("org".equals(type)) {
            rbacGrantOrgTreeService.checkWithOrg(GrantTypeEnum.MENU, ids, rootNode);
        } else if ("permissionGroup".equals(type)) {
            rbacGrantPermGroupTreeService.checkWithPermGroup(GrantTypeEnum.MENU, ids, rootNode);
        } else if ("develop".equals(type)) {
            rbacGrantDevelopTreeService.checkWithDevelop(GrantTypeEnum.MENU, ids, rootNode);
        }

        return rootNode;
    }

    @Override
    public JSONTreeNode loadFuncPermissions(String type, String ids, String... funcIds) {
        JSONTreeNode rootNode = TreeUtil.buildRootNode();
        if (funcIds == null || funcIds.length <= 0) {
            return rootNode;
        }

        List<String> funcIdList = Arrays.asList(funcIds);
        Map<String, List<DynaBean>> funcResult = metaFuncRpcService.findPermedFuncsAndChildFuncsWithButtonsByFuncIds(funcIdList);
        //功能
        List<DynaBean> mainFuncList = funcResult.get("main");
        //子功能
        List<DynaBean> childFuncRelationList = funcResult.get("child");
        //按钮
        List<DynaBean> funcButtonList = funcResult.get("button") == null ? new ArrayList<>() : funcResult.get("button");
        //子功能所属功能
        List<String> subFuncRelationIdList = new ArrayList<>();
        if (childFuncRelationList != null && !childFuncRelationList.isEmpty()) {
            childFuncRelationList.forEach(each -> {
                subFuncRelationIdList.add(each.getStr("JE_CORE_FUNCRELATION_ID"));
            });
        }
        Map<String, DynaBean> funcIdCodeMap = metaFuncRpcService.findSubFuncParentFuncInfos(subFuncRelationIdList);

        //主功能
        for (DynaBean eachFuncBean : mainFuncList) {
            //此处设置功能展示权限，用于check校验
            eachFuncBean.set("PERM_SHOW", pcFuncBaseService.formatPcFuncShowTemplate(eachFuncBean.getStr("FUNCINFO_FUNCCODE")));
            //设置功能按钮的功能属性，用于构建树形
            for (DynaBean eachButtonBean : funcButtonList) {
                if (eachFuncBean.getStr("JE_CORE_FUNCINFO_ID").equals(eachButtonBean.getStr("RESOURCEBUTTON_FUNCINFO_ID"))) {
                    eachButtonBean.set("FUNCINFO_FUNCCODE", eachFuncBean.getStr("FUNCINFO_FUNCCODE"));
                    //此处生成展示权限编码，用于check校验
                    eachButtonBean.set("PERM_SHOW", pcFuncButtonService.formatPcFuncButtonShowTemplate(eachFuncBean.getStr("FUNCINFO_FUNCCODE"),
                            eachButtonBean.getStr("RESOURCEBUTTON_CODE")));
                }
            }
        }

        //子功能
        for (int i = 0; childFuncRelationList != null && !childFuncRelationList.isEmpty() && i < childFuncRelationList.size(); i++) {
            //此处设置子功能展示权限，用于check校验
            if ("func".equals(childFuncRelationList.get(i).getStr("FUNCRELATION_RELYONTYPE"))) {
                childFuncRelationList.get(i).set("PERM_SHOW", pcSubFuncRelationService.formatPcSubFuncRelationShowTemplate(getFuncCode(funcIdCodeMap.get(childFuncRelationList.get(i).getStr("JE_CORE_FUNCRELATION_ID"))), childFuncRelationList.get(i).getStr("FUNCRELATION_CODE")));
                //设置功能按钮的功能属性，用于构建树形
                for (DynaBean eachButtonBean : funcButtonList) {
                    if (childFuncRelationList.get(i).getStr("FUNCRELATION_FUNCID").equals(eachButtonBean.getStr("RESOURCEBUTTON_FUNCINFO_ID"))) {
                        eachButtonBean.set("FUNCINFO_FUNCCODE", childFuncRelationList.get(i).getStr("FUNCRELATION_CODE"));
                        //此处生成展示权限编码，用于check校验
                        eachButtonBean.set("PERM_SHOW", pcFuncButtonService.formatPcFuncButtonShowTemplate(childFuncRelationList.get(i).getStr("FUNCRELATION_CODE"),
                                eachButtonBean.getStr("RESOURCEBUTTON_CODE")));
                    }
                }
            } else {
                childFuncRelationList.get(i).set("PERM_SHOW", pcSubFuncRelationService.formatPcSubFuncRelationShowTemplate(getFuncCode(funcIdCodeMap.get(childFuncRelationList.get(i).getStr("JE_CORE_FUNCRELATION_ID"))), childFuncRelationList.get(i).getStr("FUNCRELATION_CODE")));
            }
        }

        for (DynaBean eachFuncBean : mainFuncList) {
            JSONTreeNode eachNode = new JSONTreeNode();
            eachNode.setId(eachFuncBean.getStr("JE_CORE_FUNCINFO_ID"));
            eachNode.setCode(eachFuncBean.getStr("FUNCINFO_FUNCCODE"));
            eachNode.setText(eachFuncBean.getStr("FUNCINFO_FUNCNAME"));
            eachNode.setNodeInfo(eachFuncBean.getStr("FUNCINFO_FUNCCODE"));
            eachNode.setNodeInfoType("MT");
            eachNode.setNodeType("GENERAL");
            eachNode.setChecked(false);
            eachNode.setParent(rootNode.getId());
            eachNode.setLayer("1");
            eachNode.setLeaf(false);
            eachNode.setIcon(eachFuncBean.getStr("FUNCINFO_ICON"));
            eachNode.setDisabled("0");
            eachNode.setBean(eachFuncBean.getValues());
            for (DynaBean eachButtonBean : funcButtonList) {
                if (eachButtonBean.getStr("FUNCINFO_FUNCCODE").equals(eachNode.getNodeInfo())) {
                    eachNode.getChildren().add(buildButtonTreeNode(eachButtonBean, eachNode.getId()));
                }
            }
            buildSubFuncTreeNode(eachNode, childFuncRelationList, funcButtonList);
            rootNode.getChildren().add(eachNode);
        }

        //权限校验check
        if ("role".equals(type)) {
            rbacGrantRoleTreeService.checkWithRole(GrantTypeEnum.FUNC, ids, rootNode);
        } else if ("department".equals(type)) {
            rbacGrantDepartmentTreeService.checkWithDepartment(GrantTypeEnum.FUNC, ids, rootNode);
        } else if ("org".equals(type)) {
            rbacGrantOrgTreeService.checkWithOrg(GrantTypeEnum.FUNC, ids, rootNode);
        } else if ("permissionGroup".equals(type)) {
            rbacGrantPermGroupTreeService.checkWithPermGroup(GrantTypeEnum.FUNC, ids, rootNode);
        } else if ("develop".equals(type)) {
            rbacGrantDevelopTreeService.checkWithDevelop(GrantTypeEnum.FUNC, ids, rootNode);
        }

        return rootNode;
    }

    @Override
    public JSONTreeNode loadAppPermissions(String appId) {
        return null;
    }

    private void recursiveSetMenuFuncInfo(JSONTreeNode rootNode, List<DynaBean> mainFuncInfoBeanList, List<DynaBean> childFuncRelationBeanList, List<DynaBean> funcButtonBeanList) {
        if (rootNode.getChildren().isEmpty()) {
            return;
        }

        //由于一直在追加，递归会重新递归已经设置好的功能和子功能，此处的逻辑是已经递归设置的不再重新递归，放置重复计算
        if (!"ROOT".equals(rootNode.getId())
                && "MT".equals(rootNode.getNodeInfoType())
                && !rootNode.getBean().containsKey("JE_CORE_MENU_ID")) {
            return;
        }

        for (JSONTreeNode eachChildNode : rootNode.getChildren()) {
            //如果是功能，则进行递归设置
            if ("MT".equals(eachChildNode.getNodeInfoType())) {
                for (DynaBean eachMainFuncBean : mainFuncInfoBeanList) {
                    if (!eachMainFuncBean.getStr("FUNCINFO_FUNCCODE").equals(eachChildNode.getNodeInfo())) {
                        continue;
                    }
                    eachChildNode.setBean(eachMainFuncBean.getValues());
                    eachChildNode.setIcon("jeicon jeicon-function");
                    for (DynaBean eachButtonBean : funcButtonBeanList) {
                        if (eachButtonBean.getStr("FUNCINFO_FUNCCODE").equals(eachChildNode.getNodeInfo())) {
                            eachChildNode.getChildren().add(buildButtonTreeNode(eachButtonBean, eachChildNode.getId()));
                        }
                    }
                    buildSubFuncTreeNode(eachChildNode, childFuncRelationBeanList, funcButtonBeanList);
                }
            }
            recursiveSetMenuFuncInfo(eachChildNode, mainFuncInfoBeanList, childFuncRelationBeanList, funcButtonBeanList);
        }
    }

    private void buildSubFuncTreeNode(JSONTreeNode parentNode, List<DynaBean> childFuncRelationBeanList, List<DynaBean> funcButtonBeanList) {
        String parentBeanId;
        for (int i = 0; childFuncRelationBeanList != null && !childFuncRelationBeanList.isEmpty() && i < childFuncRelationBeanList.size(); i++) {
            if ("commonSubFunc".equals(parentNode.getNodeInfoType())) {
                parentBeanId = (String) parentNode.getBean().get("JE_CORE_FUNCRELATION_ID");
            } else {
                parentBeanId = parentNode.getBean().get("JE_CORE_FUNCINFO_ID") == null ? null : (String) parentNode.getBean().get("JE_CORE_FUNCINFO_ID");
            }
            if (!Strings.isNullOrEmpty(parentBeanId) && childFuncRelationBeanList.get(i).getStr("FUNCRELATION_FUNCINFO_ID").equals(parentBeanId)) {
                JSONTreeNode node = new JSONTreeNode();
                node.setId(childFuncRelationBeanList.get(i).getStr("JE_CORE_FUNCRELATION_ID"));
                node.setParent(parentNode.getId());
                node.setLeaf(true);
                node.setText(childFuncRelationBeanList.get(i).getStr("FUNCRELATION_NAME") + "->功能");
                node.setCode(childFuncRelationBeanList.get(i).getStr("FUNCRELATION_CODE"));
                node.setIcon("jeicon jeicon-function");
                node.setNodeType("GENERAL");
                node.setNodeInfo(childFuncRelationBeanList.get(i).getStr("FUNCRELATION_CODE"));
                node.setBean(childFuncRelationBeanList.get(i).getValues());
                node.setChecked(false);
                if ("func".equals(childFuncRelationBeanList.get(i).getStr("FUNCRELATION_RELYONTYPE"))) {
                    node.setNodeInfoType("commonSubFunc");
                    for (DynaBean eachButtonBean : funcButtonBeanList) {
                        if (eachButtonBean.getStr("FUNCINFO_FUNCCODE").equals(node.getNodeInfo())) {
                            node.getChildren().add(buildButtonTreeNode(eachButtonBean, childFuncRelationBeanList.get(i).getStr("FUNCRELATION_FUNCINFO_ID")));
                        }
                    }
                } else {
                    node.setNodeInfoType("diySubFunc");
                }
                parentNode.getChildren().add(node);
                if (!"diySubFunc".equals(node.getNodeInfoType())) {
                    buildSubFuncTreeNode(node, childFuncRelationBeanList, funcButtonBeanList);
                }
            }
        }
    }

    private JSONTreeNode buildButtonTreeNode(DynaBean buttonBean, String parentId) {
        JSONTreeNode node = new JSONTreeNode();
        node.setId(buttonBean.getStr("JE_CORE_RESOURCEBUTTON_ID"));
        node.setParent(parentId);
        node.setLeaf(true);
        if ("GRID".equals(buttonBean.getStr("RESOURCEBUTTON_TYPE"))) {
            node.setText(buttonBean.getStr("RESOURCEBUTTON_NAME") + "->列表");
        } else if ("FORM".equals(buttonBean.getStr("RESOURCEBUTTON_TYPE"))) {
            node.setText(buttonBean.getStr("RESOURCEBUTTON_NAME") + "->表单");
        } else if ("ACTION".equals(buttonBean.getStr("RESOURCEBUTTON_TYPE"))) {
            node.setText(buttonBean.getStr("RESOURCEBUTTON_NAME") + "->ACTION");
        }
        node.setCode(buttonBean.getStr("RESOURCEBUTTON_CODE"));
        node.setIcon("fal fa-mouse");
        node.setNodeType("LEAF");
        node.setNodeInfo(buttonBean.getStr("RESOURCEBUTTON_CODE"));
        node.setNodeInfoType("button");
        node.setBean(buttonBean.getValues());
        node.setChecked(false);
        return node;
    }

    private void recursiveJsonTreeNode(JSONTreeNode template, JSONTreeNode rootNode, List<DynaBean> list) {
        if ("MT".equals(rootNode.getNodeInfoType())) {
            rootNode.setIcon("jeicon jeicon-function");
        }

        if (list == null || list.isEmpty()) {
            return;
        }

        JSONTreeNode treeNode;
        for (DynaBean eachBean : list) {
            if (rootNode.getId().equals(eachBean.getStr("SY_PARENT"))) {
                treeNode = buildTreeNode(template, rootNode.getId(), eachBean);
                if ("MENU".equals(treeNode.getNodeInfoType())) {
                    treeNode.setNodeInfo(treeNode.getId());
                }
                rootNode.getChildren().add(treeNode);
            }
        }

        if (rootNode.getChildren() == null || rootNode.getChildren().isEmpty()) {
            rootNode.setLeaf(true);
            return;
        }

        rootNode.setLeaf(false);

        for (JSONTreeNode eachNode : rootNode.getChildren()) {
            recursiveJsonTreeNode(template, eachNode, list);
        }

    }

    /**
     * 构建树形节点
     *
     * @param template     模板
     * @param parentNodeId 父节点ID
     * @param bean         当前bean
     * @return
     */
    private JSONTreeNode buildTreeNode(JSONTreeNode template, String parentNodeId, DynaBean bean) {
        JSONTreeNode node = new JSONTreeNode();
        node.setId(bean.getPkValue());
        node.setParent(parentNodeId);
        node.setLeaf(true);
        if (StringUtil.isNotEmpty(template.getText())) {
            node.setText(bean.getStr(template.getText()));
        }
        if (StringUtil.isNotEmpty(template.getCode())) {
            node.setCode(bean.getStr(template.getCode()));
        }
        //节点信息
        if (StringUtil.isNotEmpty(template.getNodeInfo())) {
            node.setNodeInfo(bean.getStr(template.getNodeInfo()));
        }
        //节点信息类型
        if (StringUtil.isNotEmpty(template.getNodeInfoType())) {
            node.setNodeInfoType(bean.getStr(template.getNodeInfoType()));
        }
        //节点类型
        if (StringUtil.isNotEmpty(template.getNodeType())) {
            node.setNodeType(bean.getStr(template.getNodeType()));
        }
        //节点路径
        if (StringUtil.isNotEmpty(template.getNodePath())) {
            node.setNodePath(bean.getStr(template.getNodePath()));
        }
        //是否禁用
        if (StringUtil.isNotEmpty(template.getDisabled())) {
            node.setDisabled(bean.getStr(template.getDisabled()));
        }
        //树形排序
        if (StringUtil.isNotEmpty(template.getTreeOrderIndex())) {
            node.setTreeOrderIndex(bean.getStr(template.getTreeOrderIndex()));
        }
        //节点类型
        if (StringUtil.isNotEmpty(template.getNodeType())) {
            node.setNodeType(bean.getStr(template.getNodeType()));
        }
        //图标样式
        if (StringUtil.isNotEmpty(template.getIcon())) {
            node.setIcon(bean.getStr(template.getIcon()));
        }
        //是否禁用
        if (StringUtil.isNotEmpty(template.getDisabled())) {
            node.setDisabled(bean.getStr(template.getDisabled()));
        } else {
            node.setDisabled("0");
        }
        //描述
        if (StringUtil.isNotEmpty(template.getDescription())) {
            node.setDescription(bean.getStr(template.getDescription()));
        }
        //排序
        if (StringUtil.isNotEmpty(template.getOrderIndex())) {
            node.setOrderIndex(bean.getStr(template.getOrderIndex()) + "");
        }
        node.setChecked(false);
        if (!"MT".equals(node.getNodeInfoType())) {
            bean.set("PERM_SHOW", pcMenuDataService.formatMenuDataShowTemplate(bean.getStr("JE_CORE_MENU_ID")));
        }
        node.setBean(bean.getValues());
        return node;
    }
}
